package com.castle.fortress.admin.flowable.delegate;

import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.castle.fortress.admin.flowable.form.service.FlowableFormDataService;
import com.castle.fortress.admin.flowable.form.service.impl.FlowableFormDataServiceImpl;
import com.castle.fortress.admin.oa.entity.AttendanceRecordEntity;
import com.castle.fortress.admin.oa.entity.DayStatisticsEntity;
import com.castle.fortress.admin.oa.enums.AttendanceRecordStatusEnum;
import com.castle.fortress.admin.oa.enums.AttendanceRecordTypeEnum;
import com.castle.fortress.admin.oa.service.AttendanceRecordService;
import com.castle.fortress.admin.oa.service.DayStatisticsService;
import com.castle.fortress.admin.oa.service.impl.AttendanceRecordServiceImpl;
import com.castle.fortress.admin.oa.service.impl.DayStatisticsServiceImpl;
import com.castle.fortress.admin.utils.SpringUtils;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;
import org.flowable.engine.impl.RuntimeServiceImpl;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;

/**
 * 出差申请通过  需要将打卡统计修改为出差
 *
 * @author castle
 */
@Scope(SCOPE_PROTOTYPE)
@Component
public class FortressBusinessTripPassDelegate implements JavaDelegate {

    private RuntimeService runtimeService = SpringUtils.getBean(RuntimeServiceImpl.class);
    private FlowableFormDataService flowableFormDataService = SpringUtils.getBean(FlowableFormDataServiceImpl.class);
    private AttendanceRecordService attendanceRecordService = SpringUtils.getBean(AttendanceRecordServiceImpl.class);
    private DayStatisticsService dayStatisticsService = SpringUtils.getBean(DayStatisticsServiceImpl.class);

    @Override
    public void execute(DelegateExecution delegateExecution) {

        //todo 提交出差流程的时候 需要写入 variables以下字段
        /**
         * dept_id  提交用户部门id
         * sett_id  用户考勤设置id
         * address  用户提交的出差地址
         * dates    计算出差天数接口返回的请假日期   例如 2022-10-01,上午~2022-10-02,全天~2022-10-03,上午
         */
        //出差需要生成正常的统计记录
        //出差申请 需要计算到底出差了多长时间 去查询那几天是否需要需要打卡 如果有需要打卡的那么生成  打卡记录  统计记录
        final String userId = delegateExecution.getVariable("_castle_flowable_start_userid").toString();
        final String deptId = delegateExecution.getVariable("dept_id").toString();
        final String settId = delegateExecution.getVariable("sett_id").toString();
        final String address = delegateExecution.getVariable("address").toString();
        final List<String> dates = Arrays.asList(delegateExecution.getVariable("dates").toString().split("~"));
        final ArrayList<AttendanceRecordEntity> entities = new ArrayList<>();
        final ArrayList<DayStatisticsEntity> dayStatisticsEntities = new ArrayList<>();

        ArrayList<String> dayStatisticsDates = new ArrayList<>();

        ArrayList<String> removeAm = new ArrayList<>();
        ArrayList<String> removeDay = new ArrayList<>();
        ArrayList<String> removePm = new ArrayList<>();

        for (String date : dates) {
            String[] tempDate = date.split(",");
            String dateStr = tempDate[0];
            String time = tempDate[1];
            if ("上午".equals(time) || "下午".equals(time)) {
                AttendanceRecordEntity temp = new AttendanceRecordEntity();
                temp.setUserId(Long.parseLong(userId));
                temp.setSettId(Long.valueOf(settId));
                temp.setDate(dateStr);
                temp.setClockIn(new Date());
                temp.setDeptId(Long.parseLong(deptId));
                temp.setRange("0,0");
                temp.setAddress(address);
                temp.setType("上午".equals(time) ? AttendanceRecordTypeEnum.AM.getCode() : AttendanceRecordTypeEnum.PM.getCode());
                temp.setStatus(AttendanceRecordStatusEnum.BUSINESS_TRIP.getCode());
                entities.add(temp);
                if ("上午".equals(time)) {
                    removeAm.add(dateStr);
                } else {
                    removePm.add(dateStr);
                }
            }
            if ("全天".equals(time)) {
                final AttendanceRecordEntity am = new AttendanceRecordEntity();
                am.setSettId(Long.valueOf(settId));
                am.setDeptId(Long.parseLong(deptId));
                am.setUserId(Long.parseLong(userId));
                am.setDate(dateStr);
                am.setClockIn(new Date());
                am.setRange("0,0");
                am.setAddress(address);
                am.setType(AttendanceRecordTypeEnum.AM.getCode());
                am.setStatus(AttendanceRecordStatusEnum.BUSINESS_TRIP.getCode());
                entities.add(am);
                final AttendanceRecordEntity pm = new AttendanceRecordEntity();
                pm.setSettId(Long.valueOf(settId));
                pm.setDeptId(Long.parseLong(deptId));
                pm.setUserId(Long.parseLong(userId));
                pm.setDate(dateStr);
                pm.setClockIn(new Date());
                pm.setRange("0,0");
                pm.setAddress(address);
                pm.setType(AttendanceRecordTypeEnum.PM.getCode());
                pm.setStatus(AttendanceRecordStatusEnum.BUSINESS_TRIP.getCode());
                entities.add(pm);
                //增加日期到统计记录
                dayStatisticsDates.add(dateStr);
                removeDay.add(dateStr);

                //统计
                final DayStatisticsEntity dayTemp = new DayStatisticsEntity();
                dayTemp.setStatus(AttendanceRecordStatusEnum.BUSINESS_TRIP.getCode());
                dayTemp.setDate(dateStr);
                dayTemp.setUserId(Long.parseLong(userId));
                dayTemp.setDeptId(Long.parseLong(deptId));
                dayTemp.setSettId(Long.valueOf(settId));
                dayStatisticsEntities.add(dayTemp);
            }
        }
        //删除已存在的  //半天的出差不会影响当天的统计 只需要修改打卡即可
        if (removeAm.size() > 0) {
            final QueryWrapper<AttendanceRecordEntity> amQueryWrapper = new QueryWrapper<>();
            amQueryWrapper.eq("user_id", userId);
            amQueryWrapper.in("date", removeAm);
            amQueryWrapper.eq("type", AttendanceRecordTypeEnum.AM.getCode());
            attendanceRecordService.remove(amQueryWrapper);
        }
        if (removePm.size() > 0) {
            final QueryWrapper<AttendanceRecordEntity> pmQueryWrapper = new QueryWrapper<>();
            pmQueryWrapper.eq("user_id", userId);
            pmQueryWrapper.in("date", removePm);
            pmQueryWrapper.eq("type", AttendanceRecordTypeEnum.PM.getCode());
            attendanceRecordService.remove(pmQueryWrapper);
        }
        if (removeDay.size() > 0) {
            final QueryWrapper<AttendanceRecordEntity> dayQueryWrapper = new QueryWrapper<>();
            dayQueryWrapper.eq("user_id", userId);
            dayQueryWrapper.in("date", removeDay);
            attendanceRecordService.remove(dayQueryWrapper);
            //删除全天的统计记录
            final QueryWrapper<DayStatisticsEntity> dayStatisticsRemove = new QueryWrapper<>();
            dayStatisticsRemove.eq("user_id", userId);
            dayStatisticsRemove.in("date", removeDay);
            dayStatisticsService.remove(dayStatisticsRemove);
            //然后新增正常的记录
        }
        ListUtil.split(dayStatisticsEntities, 30).forEach(batch -> {
            dayStatisticsService.saveBatch(batch);
        });
        ListUtil.split(entities, 30).forEach(batch -> {
            attendanceRecordService.saveBatch(batch);
        });
    }
}
